package com.wm.machine.baselibrary.utils;

import android.text.format.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;


/*
 * 字母 日期或时间元素 表示 示例
 * G Era 标志符 Text AD
 * y 年 Year 1996;96
 * M 年中的月份 Month July; Jul; 07
 * w 年中的周数 Number 27
 * W 月份中的周数 Number 2
 * D 年中的天数 Number 189
 * d 月份中的天数 Number 10
 * F 月份中的星期 Number 2
 * E 星期中的天数 Text Tuesday; Tue
 * a Am/pm 标记 Text PM
 * H 一天中的小时数（0-23） Number 0
 * k 一天中的小时数（1-24） Number 24
 * K am/pm 中的小时数（0-11） Number 0
 * h am/pm 中的小时数（1-12） Number 12
 * m 小时中的分钟数 Number 30
 * s 分钟中的秒数 Number 55
 * S 毫秒数 Number 978
 * z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
 * Z 时区 RFC 822 time zone -0800
 */

/**
 * Author： chengxp
 * CreatTime： 2018/2/7
 * Description: 时间日期相关工具类
 */
public class MDateUtils {
  private static final String[] WEEK = new String[] {"天", "一", "二", "三", "四", "五", "六"};
  private static final String[] CHINESE_ZODIAC = new String[] {"猴", "鸡", "狗", "猪", "鼠", "牛", "虎",
      "兔", "龙", "蛇", "马", "羊"};
  private static final String[] ZODIAC = new String[] {"水瓶座", "双鱼座", "白羊座", "金牛座", "双子座",
      "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "魔羯座"};
  private static final int[] ZODIAC_FLAGS =
      new int[] {20, 19, 21, 21, 21, 22, 23, 23, 23, 24, 23, 22};
  private static final long ONE_SECOND = 1000;
  private static final long ONE_MINUTE = ONE_SECOND * 60;
  private static final long ONE_HOUR = ONE_MINUTE * 60;
  private static final long ONE_DAY = ONE_HOUR * 12;
  private static final long ONE_MONTH = ONE_DAY * 30;
  private static final int ERROR = -1;
  private static final int TWO = 2;
  private static final int FOUR = 4;
  private static final int SIX = 6;
  private static final int NINE = 9;
  private static final int TEN = 10;
  private static final int ELEVEN = 11;
  private static final int TWELVE = 12;
  private static final int TWENTY_EIGHT = 28;
  private static final int TWENTY_NINE = 29;
  private static final int THIRTY = 30;
  private static final int THIRTY_ONE = 31;
  private static final int SIXTY = 60;
  private static final int ONE_HUNDRED = 100;
  private static final int FOUR_HUNDRED = 400;
  /**
   * 2018-01-01格式
   */
  public static final String YMD = "yyyy-MM-dd";
  /**
   * 2018-01-01 星期一 的格式
   */
  public static final String YMDW = "yyyy-MM-dd E";
  /**
   * 12:23:22 格式
   */
  public static final String HMS = "HH:mm:ss";
  /**
   * 12:23:22.555格式包含毫秒值
   */
  public static final String HMSS = "HH:mm:ss.SSS";
  /**
   * 2018-01-01 12:23:22 格式
   */
  public static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";
  /**
   * 2018-01-01 12:23:22.555 包含毫秒值
   */
  public static final String YMDHMSS = "yyyy-MM-dd HH:mm:ss.SSS";
  /**
   * 2018年01月01日 格式
   */
  public static final String YMD_CN = "yyyy年MM月dd日";
  /**
   * 12时23分22秒 格式
   */
  public static final String HMS_CN = "HH时mm分ss秒";
  /**
   * 2018年01月01日 12时23分22秒 格式
   */
  public static final String YMDHMS_CN = "yyyy年MM月dd日 HH时mm分ss秒";
  /**
   * 2018年01月01日 12时23分22秒555毫秒 格式
   */
  public static final String YMDHMSS_CN = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒";

  /**
   * 日期字符串 转换 Date
   *
   * @param time 已格式化的日期字符串
   * @param format 时间字符串对应的format字符串
   * @return Date对象
   */
  public static Date formatTime2Date(String time, String format) {
    try {
      return new SimpleDateFormat(format).parse(time);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return new Date();
  }

  /**
   * Date 转换成格式化的日期字符串
   *
   * @param date 要转换的date
   * @param format 期望的format字符串：yyyy-MM-dd、YMD_CN、...
   * @return 日期字符串
   */
  public static String date2Format(Date date, String format) {
    return new SimpleDateFormat(format).format(date);
  }

  /**
   * 时间戳（long） 转换 String
   *
   * @param time 时间戳
   * @param format 期望的format字符串：yyyy-MM-dd、YMD_CN、...
   * @return 日期字符串
   */
  public static String timestamp2Formmat(long time, String format) {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    String s = sdf.format(time);
    return s;
  }

  /**
   * 格式化的日期 转换成时间戳
   *
   * @param time 已格式化的日期
   * @param format 日期的format字符串
   * @return 0：格式化失败
   */
  public static long formatTime2Stamp(String time, String format) {
    try {
      SimpleDateFormat sdf = new SimpleDateFormat(format);
      return sdf.parse(time).getTime();
    } catch (ParseException e) {
      return 0;
    }
  }

  /**
   * 获得当前格式化的日期
   *
   * @param format 期望的format字符串：yyyy-MM-dd、YMD_CN、...
   * @return 日期字符串
   */
  public static String getCurDateStr(String format) {
    // Date date = Calendar.getInstance().getTime();
    Date date = getCurrentDate();
    return date2Format(date, format);
  }

  /**
   * 获得当前日期 Date 对象
   * 
   * @return Date对象
   */
  public static Date getCurrentDate() {
    return new Date();
  }

  /**
   * Date 转换 MM月dd日 星期
   *
   * @param date 要转换的date
   * @return 日期字符串
   */
  public static String date2ymdWeek(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
    return new SimpleDateFormat("MM月dd日 星期").format(date) + WEEK[dayOfWeek - 1];
  }

  /**
   * Date 转换 yyyy年MM月dd日 星期
   *
   * @param date 要转换的date
   * @return 日期字符串
   */
  public static String date2mdWeek(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
    return new SimpleDateFormat("yyyy年MM月dd日 星期").format(date) + WEEK[dayOfWeek - 1];
  }

  /**
   * 获取格式化日期字符串 的年份
   *
   * @param time 格式化的日期字符串
   * @param format 时间字符串对应的format字符串
   * @return 年份
   */
  public static int parseYear(String time, String format) {
    Calendar calendar = Calendar.getInstance();
    Date date = formatTime2Date(time, format);
    calendar.setTime(date);
    return calendar.get(Calendar.YEAR);
  }

  /**
   * 获取Date 对象的年份
   *
   * @param date Date 对象
   * @return 年份
   */
  public static int parseYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.YEAR);
  }

  /**
   * 获取格式化日期字符串 的月份
   *
   * @param time 格式化的日期字符串
   * @param format 时间字符串对应的format字符串
   * @return 月份
   */
  public static int parseMonth(String time, String format) {
    Calendar calendar = Calendar.getInstance();
    Date date = formatTime2Date(time, format);
    calendar.setTime(date);
    return calendar.get(Calendar.MONTH);
  }

  /**
   * 获取Date 对象的月份
   *
   * @param date Date 对象
   * @return 月份
   */
  public static int parseMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.MONTH);
  }

  /**
   * 获取格式化日期字符串 的日期
   *
   * @param time 格式化的日期字符串
   * @param format 时间字符串对应的format字符串
   * @return 具体第几天
   */
  public static int parseDay(String time, String format) {
    Calendar calendar = Calendar.getInstance();
    Date date = formatTime2Date(time, format);
    calendar.setTime(date);
    return calendar.get(Calendar.DAY_OF_MONTH);
  }

  /**
   * 获取Date 对象的日期
   * 
   * @param date Date 对象
   * @return 具体第几天
   */
  public static int parseDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.DAY_OF_MONTH);
  }

  /**
   * 获取指定日期 所属月的第一天
   *
   * @param date 特定日期的date对象
   * @return Date 对象
   */
  public static Date getFirstDayOfMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(calendar.get(Calendar.YEAR),
        calendar.get(Calendar.MONTH), 1);
    return calendar.getTime();
  }

  /**
   * 获取特定年 特定月 的第一天
   *
   * @param year 年份
   * @param month 月份
   * @return Date对象
   */
  public static Date getFirstDayOfMonth(Integer year, Integer month) {
    Calendar calendar = Calendar.getInstance();
    if (year == null) {
      year = calendar.get(Calendar.YEAR);
    }
    if (month == null) {
      month = calendar.get(Calendar.MONTH);
    }
    calendar.set(year, month, 1);
    return calendar.getTime();
  }

  /**
   * 获取特定日期 所属月的最后一天
   *
   * @param date 特定日期的date对象
   * @return Date对象
   */
  public static Date getLastDayOfMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(calendar.get(Calendar.YEAR),
        calendar.get(Calendar.MONTH), 1);
    calendar.roll(Calendar.DATE, ERROR);
    return calendar.getTime();
  }

  /**
   * 获取特定日期年 指定月 的最后一天
   *
   * @param year 年份
   * @param month 月份
   * @return Date对象
   */
  public static Date getLastDayOfMonth(Integer year, Integer month) {
    Calendar calendar = Calendar.getInstance();
    if (year == null) {
      year = calendar.get(Calendar.YEAR);
    }
    if (month == null) {
      month = calendar.get(Calendar.MONTH);
    }
    calendar.set(year, month, 1);
    calendar.roll(Calendar.DATE, ERROR);
    return calendar.getTime();
  }

  /**
   * 比较参数2是否大于参数1的时间
   *
   * @param front 参数1时间字符串
   * @param rear 参数2时间字符串
   * @param format 时间字符串对应的format字符串
   * @return true:大于
   */
  public static boolean compare2Time(String front, String rear, String format) {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    try {
      // 转化为时间
      Date date1 = sdf.parse(front);
      Date date2 = sdf.parse(rear);
      return date1.after(date2);
    } catch (ParseException e) {
      e.printStackTrace();
      return false;
    }
  }


  /**
   * 获取对应年份的生肖
   *
   * @param year 年份
   * @return 生肖字符串
   */
  public static String getChineseZodiac(int year) {
    return CHINESE_ZODIAC[year % TWELVE];
  }

  /**
   * 获取Date对象 对应的生肖
   *
   * @param date Date 对象
   * @return 生肖
   */
  public static String getChineseZodiac(Date date) {
    int year = parseYear(date);
    return getChineseZodiac(year);
  }

  /**
   * 获取格式化日期 对应的生肖
   *
   * @param time 格式化的日期字符串
   * @param format 日期对应的format 字符串
   * @return 生肖
   */
  public static String getChineseZodiac(String time, String format) {
    int year = parseYear(time, format);
    return getChineseZodiac(year);
  }

  /**
   * 获取给定 日期所属星座
   *
   * @param month 月份
   * @param day 该月中的第几天
   * @return 星座
   */
  public static String getZodiac(int month, int day) {
    return ZODIAC[day >= ZODIAC_FLAGS[month - 1] ? month - 1 : (month + TEN) % TWELVE];
  }

  /**
   * 获取格式化日期 对应的星座
   *
   * @param time 格式化的日期字符串
   * @param format 日期对应的format 字符串
   * @return 星座
   */
  public static String getZodiac(String time, String format) {
    int month = parseMonth(time, format);
    int day = parseDay(time, format);
    return getZodiac(month, day);
  }

  /**
   * 获取给定 日期Date 对象对应星座
   *
   * @param date Date对象
   * @return 星座
   */
  public static String getZodiac(Date date) {
    int month = parseMonth(date);
    int day = parseDay(date);
    return getZodiac(month, day);
  }

  /**
   * 判断平年闰年
   *
   * @param year 要判断的年份
   * @return true 表示闰年，false表示平年
   */
  public boolean isLeapYear(int year) {
    if (year % FOUR_HUNDRED == 0) {
      return true;
    } else if (year % ONE_HUNDRED != 0 && year % FOUR == 0) {
      return true;
    }
    return false;
  }

  /**
   * 计算某月的天数
   *
   * @param year 年份
   * @param month 现实生活中的月份，不是系统存储的月份，从1到12
   * @return 天数
   */

  public int getDaysOfMonth(int year, int month) {
    if (month < 1 || month > TWELVE) {
      return 0;
    }
    boolean isLeapYear = isLeapYear(year);
    int daysOfMonth = 0;
    switch (month) {
      case FOUR:
      case SIX:
      case NINE:
      case ELEVEN:
        daysOfMonth = THIRTY;
        break;
      case TWO:
        if (isLeapYear) {
          daysOfMonth = TWENTY_NINE;
        } else {
          daysOfMonth = TWENTY_EIGHT;
        }
        break;
      default:
        daysOfMonth = THIRTY_ONE;
        break;

    }
    return daysOfMonth;
  }

  /**
   * 获取格式化的日期 的月份的总天数
   *
   * @param time 格式化的日期
   * @param format 日期的format 字符串
   * @return 该月总天数
   */
  public int getDaysOfMonth(String time, String format) {
    int year = parseYear(time, format);
    int month = parseMonth(time, format);
    return getDaysOfMonth(year, month);
  }

  /**
   * 将日期格式化成友好的字符串：几分钟前、几小时前、几天前、几月前、刚刚
   *
   * @param date Date 对象
   * @return 格式化后的字符串
   */
  public static String formatFriendly(Date date) {
    String returStr = null;
    if (date == null) {
      return returStr;
    }
    long diff = new Date().getTime() - date.getTime();
    long r = 0;

    if (diff > ONE_MONTH) {
      r = (diff / ONE_MONTH);
      returStr = r + "个月前";
    } else if (diff > ONE_DAY) {
      r = (diff / ONE_DAY);
      returStr = r + "天前";
    } else if (diff > ONE_HOUR) {
      r = (diff / ONE_HOUR);
      returStr = r + "个小时前";
    } else if (diff > ONE_MINUTE) {
      r = (diff / ONE_MINUTE);
      returStr = r + "分钟前";
    } else {
      returStr = "刚刚";
    }
    return returStr;
  }

  /**
   * LrcView 专用时间格式化方法
   *
   * @param milli 毫秒值
   * @return 格式化后的字符串
   */
  public static String formatTimeLrc(long milli) {
    int m = (int) (milli / DateUtils.MINUTE_IN_MILLIS);
    int s = (int) ((milli / DateUtils.SECOND_IN_MILLIS) % SIXTY);
    String mm = String.format(Locale.getDefault(), "%02d", m);
    String ss = String.format(Locale.getDefault(), "%02d", s);
    return mm + ":" + ss;
  }
}
